Using ADwin as a Multi-Channel Trigger Controller by Introduction Test system trigger controllers act as the central hub for sequencing test instruments. Using ADwin as the trigger controller allows the system to run much faster than implementing software triggers. The real-time nature of ADwin allows precise timing of triggers in and out of the test rack, which can open up new testing possibilities.. Building real-time control systems is difficult, if not impossible, with Microsoft® Windows® in the control loop. With the introduction of the ADwin system, high-speed, real-time data acquisition, process control, and analysis are now available in the Windows environment. The ADwin system provides assorted combinations of analog inputs and outputs as well as digital inputs and outputs. A dedicated microprocessor that can be programmed to perform most control applications is combined with the available I/O. Having a processor dedicated to controlling the I/O allows for reaction times down to 280ns. As measurements and test data integrity become increasingly important, eliminating variability from the production process also increases in importance. Eliminating timing variability in the test system often requires precise trigger control. This note will show and explain the steps involved in building an example trigger controller with ADwin. Test Description For steady-state testing, the output of a source is set to a level and the device under test (DUT) is allowed to settle before the measurement is taken. This approach to testing is shown in Figure 1. Figure 1. Effect of Measurement Timing Latencies on Steady-State Measurements The ideal time to begin measuring the DUT output level is Td, which is just after it has settled. A measurement at this time will be accurate and can be taken with minimum delay. This is the ideal case, but in practice, there is usually some measurement latency, resulting in the measurement actually being taken between Td and Tm. Measurement latencies can occur from measurement processing time, program execution time, software interrupts, and instrument command processing time, which ultimately reduce throughput. For devices with dynamic output signals, measurements are often taken at several points in time. Taking several measurements can be useful for time domain, rise time, or frequency analysis. Figure 2 shows the effects of timing issues when measuring dynamic outputs. Figure 2. Effect of Trigger Timing Jitter and Latencies on Dynamic Signal Measurements The times T1 through T6, shown in Figure 2, represent the desired measurement times needed to characterize the DUT. Looking at T1, the trigger timing uncertainty (jitter) means that the reading can actually occur at any time between T- and T+. The uncertainty can yield measured values between V- and V+, which implies that timing jitter or overall timebase accuracy are potential sources of error in the test system. Test System Description A typical test configuration consists of some kind of source to provide stimulus to the device under test (DUT) and a measurement device to measure the response of the DUT. The actions of the test system are usually controlled with a computer through the IEEE-488 interface. This typical system is shown in Figure 3. Figure 3. Typical GPIB-Based Test System The system shown in Figure 3 triggers the instruments with software. Triggering with software is common because of its flexibility and ease of implementation. Be aware, however, that software triggering lends itself to large amounts of jitter. Time variation between two subsequent events in Windows may vary by up to 50ms, even for compiled programs written in C++. For many applications, having up to 50ms of jitter in the timebase between measurements is unacceptable. Figure 4 shows a test system configuration using ADwin as an external trigger controller. In this system, ADwin monitors the output of the source and triggers the meter to begin measuring the DUT. The ADwin system can reduce trigger jitter by over 100 times in this configuration. Figure 4. ADwin System Block Diagram The ADwin system shown in Figure 4 monitors the source output with an analog input channel. When it sees a rising edge from the source, it delays for a programmable amount of time, then sends an output trigger to the instrument via a digital output line. Figure 5 illustrates an ADwin system controlling ten sets of instruments simultaneously. Figure 5. ADwin Controlling a 10-Channel System Methods and Techniques Analog and Digital I/O For a trigger control unit using the analog input to monitor each instrument, the number of inputs must equal the number of digital outputs used to send the trigger signal to each. The number of input/output pairs available for each of the ADwin products is summarized in Table 1. Table 1. ADwin Family Analog Input Selection
Digital Triggering State Machine Figure 6. States of a Voltage Pulse for Trigger Controller Implementation The first state of the state machine is detecting the rising edge of the voltage pulse with an analog input channel. The second state involves delaying a programmed amount of time (i.e., trigger delay). The third state represents actually sending the digital output trigger to the instrument to start the measurement. After the trigger, ADwin must wait and detect the falling edge of the pulse to see that the pulse has been completed. Once the falling edge has been detected and the fourth state has been reached, the state machine resets and the hardware monitors the analog input at the first state. Basic Programming Guidelines The following example program is used to implement the test system shown in Figure 5. The program was written in ADbasic and was compiled and run on the ADwin processor. |
' Define User inputs to the ADwin configuration #DEFINE CountsThresh par_1 ' Voltage threshold for second test #DEFINE Delay par_2 ' Delay before trigger for 1st test #DEFINE Hysterisis par_3 ' Limit effect of noise on threshold ' Define ADwin outputs to be read by the user program #DEFINE ADChan1 par_5 ' AD counts from ADwin card #DEFINE ADChan2 par_6 ' Each variable represents a meter #DEFINE ADChan3 par_7 #DEFINE ADChan4 par_8 #DEFINE ADChan5 par_9 #DEFINE ADChan6 par_10 #DEFINE ADChan7 par_11 #DEFINE ADChan8 par_12 #DEFINE ADChan9 par_13 #DEFINE ADChan10 par_14 ' Define User input floating point parameters #DEFINE VoltThreshold fpar_1 ' Voltage threshold for first test ' Define Program Flags with understandable names #DEFINE Unipolar 1 #DEFINE Bipolar 0 #DEFINE ON 1 #DEFINE OFF 0 ' Define state machine variables #DEFINE S0 0 ' Wait for 20V #DEFINE S1 1 ' Delay before sending output trigger #DEFINE S2 2 ' Send output trigger #DEFINE S3 3 ' Wait for V-src off DIM State[10] AS SHORT ' Array of states for each channel DIM Reading[10] AS LONG ' Array for ADC counts DIM Counter[10] AS INTEGER ' Array of delays for each channel DIM Vsrc[10] AS INTEGER ' Save state of each meter Volt Source DIM LocStateOdd AS INTEGER ' Place holder for state machine DIM LocStateEven AS INTEGER ' Place holder for state machine DIM NumMeter AS INTEGER ' Define number of meters in use DIM Polarity AS INTEGER ' Define polarity of voltage input DIM DelayCounts AS LONG ' Clock cycles for 1st delay DIM MaxVoltInput AS FLOAT ' Maximum input setting for board DIM FullRange AS FLOAT ' Define full range of input for board DIM TempTime AS FLOAT ' Temporary variable for ADwin timer DIM MuxNum AS INTEGER ' Define mux channel for ADCs DIM InputCounts1 AS INTEGER ' Hold counts from ADC1 DIM InputCounts2 AS INTEGER ' Hold counts from ADC2 DIM DummyExp AS FLOAT ' Hold dummy value for exponent calc DIM a,b,i,j,k AS INTEGER ' Loop variables SUB TakeRdgs(Mux) SET_MUX(45) ' Set mux to Grounded channel SET_MUX(Mux) ' Set mux to desired channels DummyExp = 4^3 ' Delay to let mux settle START_CONV(3) ' Start A/D conversion WAIT_EOC(3) ' Wait until ADCs are done InputCounts1 = READADC(1) ' Read ADC1 counts into variable InputCounts2 = READADC(2) ' Read ADC2 counts into variable ENDSUB INIT: ' INIT section is run once at beginning ' Initialize various ADwin functions CONF_DIO 15 ' Configure digital I/O DIGOUT_WORD(2047) ' Set 16-bit digital output (normal HI) GLOBALDELAY = 2500 ' Loop EVENT every 1000 25ns intervals SET_MUX(0) ' Select channel 1 for both ADC ' Initialize Program Variables NumMeter = 10 VoltThreshold = 0.3 ' Set voltage threshold for 1st test Delay = 100 ' Delay in ms for 1st test InputCounts1 = 0 ' Initialize variable InputCounts2 = 0 ' Initialize variable Hysterisis = 5 ' Noise compensation ' Calculate number of 25ns counts to reach Delay value DelayCounts = (Delay*0.001)/(25E-9) Polarity = Unipolar MaxVoltInput = 10 LocStateOdd = S0 LocStateEven = S0 ' Change voltage input from user into ADC counts IF (Polarity = Bipolar) THEN FullRange = MaxVoltInput * 2 CountsThresh = ((4096 / FullRange) * VoltThreshold) + 2048 ELSE FullRange = MaxVoltInput CountsThresh = (4096 / FullRange) * VoltThreshold ENDIF ' Initialize the various Array Variables j = 0 k = 1 ' Initialize variable FOR i = 1 to NumMeter State[i] = S0 ' Initialize each to first state Counter[i] = 0 ' Initialize each channel counter Reading[i] = 0 ' Initialize A/D value array Vsrc[i] = OFF ' Initialize all sources as off NEXT i ' MUX configuration for ADCs (10-bit) with gain=1 for both ' Binary Decimal ADC1 ADC2 Channel ' 00 00 000 000 0 1 2 ' 00 00 001 001 9 3 4 ' 00 00 010 010 18 5 6 ' 00 00 011 011 27 7 8 ' 00 00 100 100 36 9 10 ' 00 00 101 101 45 11 12 ' 00 00 110 110 54 13 14 ' 00 00 111 111 63 15 16 EVENT: ' EVENT section represents main program loop GLOBALDELAY = 2500 ' Program Loop Execution INC j ' Increment counter LocStateOdd = State[j] ' Local variable as channel state LocStateEven = State[j+1] DelayCounts = (Delay*0.001)/(25E-9) ' Calculate Delay ' ************ ACQUIRE A/D READINGS ********** IF (j = 1) THEN ' Acquire first two ADC channels MuxNum = 0 ' Define ADC Channel number TakeRdgs(MuxNum) ' Call ADC subroutine a = 1 ' Distinguish between ADCs b = 2 ADChan1 = InputCounts1 ' Output Counts to global parameters ADChan2 = InputCounts2 ENDIF ' This pattern followed for all channels IF (j = 3) THEN MuxNum = 9 TakeRdgs(MuxNum) a = 3 b = 4 ADChan3 = InputCounts1 ADChan4 = InputCounts2 ENDIF IF (j = 5) THEN MuxNum = 18 TakeRdgs(MuxNum) a = 5 b = 6 ADChan5 = InputCounts1 ADChan6 = InputCounts2 ENDIF IF (j = 7) THEN MuxNum = 27 TakeRdgs(MuxNum) a = 7 b = 8 ADChan7 = InputCounts1 ADChan8 = InputCounts2 ENDIF IF (j = 9)THEN MuxNum = 36 TakeRdgs(MuxNum) a = 9 b = 10 ADChan9 = InputCounts1 ADChan10 = InputCounts2 ENDIF Reading[a] = InputCounts1 ' Output Counts to local parameters Reading[b] = InputCounts2 ' ********** BEGINNING OF STATE MACHINE ************ IF (LocStateOdd = S0) THEN ' Wait for 1st rising edge IF (Reading[a] >= CountsThresh + Hysterisis) THEN ' Compare reading from ADC1 Counter[a] = READ_TIMER() ' Read timer to begin trig delay State[a] = S1 ' Increment state machine ENDIF ENDIF IF (LocStateEven = S0) THEN ' Wait for 1st rising edge IF (Reading[b] >= CountsThresh + Hysterisis) THEN ' Compare reading from ADC2 Counter[b] = READ_TIMER() ' Read timer to begin trig delay State[b] = S1 ' Increment state machine ENDIF ENDIF IF (LocStateOdd = S1) THEN ' Delay before triggering meter TempTime = READ_TIMER() ' Store timer in temp variable IF ((TempTime - Counter[a]) > DelayCounts) THEN ' Compare time to delay CLEAR_DIGOUT(a) ' Output trigger pulse State[a] = S2 ' Increment state machine ENDIF ENDIF IF (LocStateEven = S1) THEN ' Delay before triggering meter TempTime = READ_TIMER() ' Store timer in temp variable IF ((TempTime - Counter[b]) > DelayCounts) THEN ' Compare time to delay CLEAR_DIGOUT(b) ' Output trigger pulse State[b] = S2 ' Increment state machine ENDIF ENDIF IF (LocStateOdd = S2) THEN ' Reset trigger line SET_DIGOUT(a) ' Bring line to Normal HI State[a] = S3 ' Increment state machine ENDIF IF (LocStateEven = S2) THEN ' Reset trigger line SET_DIGOUT(b) ' Bring line to Normal HI State[b] = S3 ' Increment state machine ENDIF IF (LocStateOdd = S3) THEN ' Verify V-src is turned off IF (Reading[a] < CountsThresh - Hysterisis) THEN ' Compare ADC1 to "zero" State[a] = S0 ' Reset State Machine ENDIF ENDIF IF (LocStateEven = S3) THEN ' Verify V-src is turned off IF (Reading[b] < CountsThresh - Hysterisis) THEN ' Compare ADC2 to "zero" State[b] = S0 ' Reset State Machine ENDIF ENDIF INC j ' Increment counter ' ********* END OF STATE MACHINE ********* IF (j = NumMeter) THEN j = 0 ' Reset j if loop count equals # of meters ENDIF FINISH: ' FINISH section runs once at end of program
Example Program Keithley developed a downloadable ADbasic example program TriggerController.bas to create the trigger controller in the test system shown in Figure 5. NOTE: The test programs that are provided are intended to illustrate the concepts presented in this note. The programs may need to be altered in order to accommodate desired test parameters and timing. Equipment List
Alternative Solutions The ADwin product family offers many different form factors, processors, and I/O in which to create the PID controller. The ADwin family includes:
All three product variations can support up to 32Mbytes of RAM per processor and optional bootloader. The bootloader stores an ADbasic process(es) and begins running the process upon power-up. Therefore, once the ADwin hardware is programmed, it can be used as a stand-alone and without a PC. Keithley also offers a range of digital trigger controllers that are compatible with the instrument Trigger Link bus. The Models KPC-TM and 2361 offer additional system triggering alternatives. |
||||||||||||||||||